package ufpr.mestrado.ais.metaheuristics.misa;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import ufpr.mestrado.ais.base.operator.hipermutation.MISAMutation;

import jmetal.base.Algorithm;
import jmetal.base.Operator;
import jmetal.base.Problem;
import jmetal.base.SolutionSet;
import jmetal.base.operator.comparator.DominanceComparator;
import jmetal.base.operator.selection.BestSolutionSelection;
import jmetal.problems.ProblemFactory;
import jmetal.qualityIndicator.QualityIndicator;
import jmetal.util.Configuration;
import jmetal.util.JMException;

public class MISA_main {

	public static Logger logger_; // Logger object
	public static FileHandler fileHandler_; // FileHandler object

	/**
	 * @param args
	 * @throws IOException
	 * @throws SecurityException
	 * @throws JMException
	 * @throws ClassNotFoundException
	 */
	public static void main(String[] args) throws SecurityException,
			IOException, JMException, ClassNotFoundException {

		// Logger object and file to store log messages
		logger_ = Configuration.logger_;
		fileHandler_ = new FileHandler("MISA_main.log");
		logger_.addHandler(fileHandler_);

		// zdt default
		Object[] params = { "Real" };

		final Problem problem = (new ProblemFactory()).getProblem("ZDT6",
				params);

		final QualityIndicator indicators = new QualityIndicator(problem,
				args[0]);

		final Algorithm algorithm = new MISA(problem);

		// Algorithm parameters
		algorithm.setInputParameter("nPop", 100);
		algorithm.setInputParameter("stopCriteria", 25000);
		algorithm.setInputParameter("maxSize", 100);
		algorithm.setInputParameter("bisections", 10);

		// Add the indicator object to the algorithm
		algorithm.setInputParameter("indicators", indicators);

		// Selection operator
		final Operator selection = new BestSolutionSelection(
				new DominanceComparator());

		// Mutation operator
		final Operator mutation = new MISAMutation();

		// adiciona comparador
		algorithm.addOperator("selection", selection);
		algorithm.addOperator("hipermutation", mutation);

		// Execute the Algorithm
		long initTime = System.currentTimeMillis();
		SolutionSet population = algorithm.execute();
		long estimatedTime = System.currentTimeMillis() - initTime;

		// Result messages
		logger_.info("Total execution time: " + estimatedTime + "ms");
		logger_.info("Variables values have been writen to file VAR");
		population.printVariablesToFile("VAR");
		logger_.info("Objectives values have been writen to file FUN");
		population.printObjectivesToFile("FUN");

		if (indicators != null) {
			logger_.info("Quality indicators");
			logger_.info("Hypervolume: "
					+ indicators.getHypervolume(population));
			logger_.info("GD         : " + indicators.getGD(population));
			logger_.info("IGD        : " + indicators.getIGD(population));
			logger_.info("Spread     : " + indicators.getSpread(population));
			logger_.info("Epsilon    : " + indicators.getEpsilon(population));

			int evaluations = ((Integer) algorithm
					.getOutputParameter("evaluations")).intValue();
			logger_.info("Speed      : " + evaluations + " evaluations");
		}

	}

}
